home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / demostu2 / floor2.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-12-01  |  8.3 KB  |  387 lines

  1. PROGRAM floor2;
  2. {
  3.   Floor of Doom, second life
  4.   - by Bjarke Viksφe
  5.   oct 1994
  6.  
  7.   Use mouse and mousebuttons!
  8.   Trying to rotate the damn thing. (Jazz JackRabbit, here I come :)
  9.   Anyway, rotating a texturemapped floor is hardly a demo thing -
  10.   but a game idea? And very tricky to do.
  11.  
  12.   Ok, it's pretty much the same as "Floor1" except that I do both a x-slope
  13.   and a y-slope run.
  14.   And all rotated coords are precalc'ed (LINES*2 coords per angle). Only
  15.   half of the 512 angles are actually precalc'ed, the other half is
  16.   calc'ed using the others (by negating x/y).
  17.   Oh, it needs about 320 Kb of free memory! Quit the IDE and start it
  18.   from the prompt on machines which are low on memory...
  19. }
  20.  
  21. {$A+,B-,G+,E+,I+,N-,X+}
  22. {$IFDEF DPMI}
  23. {$C FIXED PRELOAD PERMANENT}
  24. {$ENDIF}
  25.  
  26. USES
  27.     DEMOINIT,MOUSE;
  28.  
  29. {{$DEFINE DEBUG}
  30.  
  31. TYPE
  32.     pBunk = ^BunkArray;
  33.     BunkArray = ARRAY[0..254, 0..255] of byte;
  34.     pIntegerArray = ^IntegerArray;
  35.     IntegerArray = ARRAY[0..32760] of integer;
  36.  
  37. CONST
  38.     LINES = 70; {how many lines shall we paint}
  39.     TILT = 31780; {tilt floor how much?}
  40.  
  41. VAR
  42.     map, tiles : pBunk;
  43.     LineTable : array[1..3] of pIntegerArray;
  44.     xpos,ypos, angle : word;
  45.     CoordPtr : array[0..255] of pointer;
  46.     SinusTable  : array[0..639] of integer;
  47.  
  48.  
  49. (*------------------------------------------------*)
  50.  
  51. procedure SetupSinus;
  52. var
  53.     i : integer;
  54.     v, vadd : real;
  55. begin
  56.     v:=0.0;
  57.     vadd:=(2.0*pi/512.0);
  58.     for i:=0 to 639 do begin
  59.         SinusTable[i]:=round(sin(v)*32767);
  60.         v:=v+vadd;
  61.     end;
  62. end;
  63.  
  64. procedure SetColours;
  65. {Setup ugly, more or less randomly picked, colours}
  66. var
  67.     i : integer;
  68. begin
  69.     for i:=0 to 7 do setRGB(i, i,i,i);
  70.     for i:=8 to 15 do setRGB(i, (i-5)*2,0,0);
  71.     for i:=16 to 23 do setRGB(i, 0,(i-10)*2,(i-8)*2);
  72.     for i:=24 to 31 do setRGB(i, 0,0,42);
  73.     for i:=32 to 39 do setRGB(i, 0,(i-15)*2,0);
  74.     for i:=40 to 47 do setRGB(i, i,i,i);
  75.     for i:=48 to 55 do setRGB(i, i,0,0);
  76. end;
  77.  
  78.  
  79. procedure CreateMap;
  80. {Create map.
  81.  Characters in string are indexes to tiles! 'a' is tile #0,
  82.  'b' is #1 (red one) and so...}
  83.  procedure Strip(ypos,xpos : integer; st : string);
  84.  var j : integer;
  85.  begin
  86.         for j:=1 to length(st) do st[j]:=char(ord(st[j])-ord('a'));
  87.         Move(st[1],map^[ypos,xpos],length(st));
  88.  end;
  89. var
  90.     y : integer;
  91. begin
  92.     GetMem(map,65535);
  93.     FillChar(map^,65535,#0);
  94.  
  95.     y:=20;
  96.     while y<60 do begin
  97.         Strip(y,30,'fgfgfgfgfgfgfgfgfgfg');
  98.         Strip(y+1,30,'gfgfgfgfgfgfgfgfgfgf');
  99.         if (y>35) AND (y<45) then begin Strip(y,39,'aaaaa'); Strip(y+1,39,'aaaaa'); end;
  100.         inc(y,2);
  101.     end;
  102.     Strip(20,70,'bcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbc'); Strip(21,70,'cbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb');
  103.     y:=22;
  104.     while (y<42) do begin
  105.         Strip(y,70,'bcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabc'); Strip(y+1,70,'cbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacb');
  106.         Strip(y,60,'dedede'); Strip(y+1,60,'ededed');
  107.         inc(y,2)
  108.     end;
  109.     Strip(42,70,'bcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbc');
  110.     Strip(43,70,'cbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcb');
  111. end;
  112.  
  113. procedure CreateTiles;
  114. {Create some ugly tiles. We simple choose some colours and paint
  115.  a brick with them}
  116. var
  117.     i,j : integer;
  118. begin
  119.     GetMem(tiles,65535);
  120.     FillChar(tiles^,65535,#0);
  121.  
  122.     for i:=0 to 254 do {254, not 255, to get in running under DPMI!}
  123.         for j:=0 to 255 do
  124.             tiles^[i,j]:=((j DIV 32)*8) + random(8); {make dithered tile}
  125. end;
  126.  
  127.  
  128. procedure PrecalcLines;
  129. const
  130.     XPOS = 20; {this will ajust the height of the viewer}
  131. var
  132.     q,p,i, x1,y1,x2,y2 : integer;
  133.     z,sin1,cos1 : integer;
  134.     pos,angle : word;
  135.     cx,cy : longint;
  136. begin
  137.     for i:=1 to 3 do GetMem(LineTable[i],65535);
  138.  
  139.     p:=1;
  140.     pos:=0;
  141.     angle:=0;
  142.     for q:=0 to 255 do begin
  143.         CoordPtr[q]:=@LineTable[p]^[pos];
  144.  
  145.         z:=8000;
  146.         sin1:=SinusTable[angle];
  147.         cos1:=SinusTable[angle+128];
  148.         for i:=1 to LINES do begin
  149.             x1:=LongDiv(-XPOS*65536,z); {calc first coord}
  150.             y1:=LongDiv((LINES-i)*longint(TILT),z);
  151.             cx := (LongMul(x1,cos1) - LongMul(y1,sin1)) DIV 32768; {rotate it}
  152.             cy := (LongMul(x1,sin1) + LongMul(y1,cos1)) DIV 32768;
  153.             x1:=cx;
  154.             y1:=cy;
  155.             LineTable[p]^[pos]:=x1;
  156.             LineTable[p]^[pos+1]:=y1;
  157.  
  158.             x2:=LongDiv(XPOS*65535,z); {calc second coord}
  159.             y2:=LongDiv((LINES-i)*longint(TILT),z);
  160.             cx := (LongMul(x2,cos1) - LongMul(y2,sin1)) DIV 32768; {rotate it}
  161.             cy := (LongMul(x2,sin1) + LongMul(y2,cos1)) DIV 32768;
  162.             x2:=cx;
  163.             y2:=cy;
  164.             LineTable[p]^[pos+2]:=(longint(x2-x1) SHL 11) DIV 160;
  165.             LineTable[p]^[pos+3]:=(longint(y2-y1) SHL 11) DIV 160;
  166.             inc(pos,4);
  167.  
  168.             inc(z,310);
  169.         end;
  170.  
  171.         {Check if next set of coords should be placed in other buffer, since
  172.          they cannot all fit into one 64Kb segment!!!}
  173.         if ((pos*2 + (LINES*8)) > 65200) then begin
  174.             inc(p);
  175.             pos:=0;
  176.         end;
  177.         inc(angle,1); {calc next angle}
  178.     end;
  179. end;
  180.  
  181.  
  182.  
  183. procedure InitDemo;
  184. var
  185.     i : integer;
  186. begin
  187.     ClearWholeScreen;
  188.     SetColours;
  189.     SetupSinus;
  190.  
  191.     CreateMap;
  192.     CreateTiles;
  193.     PrecalcLines;
  194.  
  195.     xpos:=1200; ypos:=800;
  196.     angle:=0;
  197. end;
  198.  
  199. procedure UninitDemo;
  200. var
  201.     i : integer;
  202. begin
  203.     FreeMem(map,65535);
  204.     FreeMem(tiles,65535);
  205.     for i:=1 to 3 do FreeMem(LineTable[i],65535);
  206. end;
  207.  
  208.  
  209. (*------------------------------------------------*)
  210.  
  211. procedure MoveHero;
  212. var
  213.     x,y, sin1,cos1 : integer;
  214.     cx,cy : longint;
  215. begin
  216.     {Determine new rotation angle}
  217.     ReadMouseMotionCounters(x,y);
  218.     angle:=(angle + x) AND 511;
  219.  
  220.     {is hero moving forward?}
  221.     if (LeftButton) then begin
  222.         sin1:=SinusTable[angle];
  223.         cos1:=SinusTable[angle+128];
  224.         x:=0;  {this is the moving speed}
  225.         y:=6;
  226.         cx := (longmul(x,cos1) - longmul(y,sin1)) DIV 32768;
  227.         cy := (longmul(x,sin1) + longmul(y,cos1)) DIV 32768;
  228.         inc(xpos,cx);
  229.         inc(ypos,cy);
  230.     end;
  231.  
  232.     {hero cannot move outside board}
  233.     if (xpos<200) then xpos:=200;
  234.     if (xpos>16384) then xpos:=16384;
  235.     if (ypos<200) then ypos:=200;
  236.     if (ypos>16384) then ypos:=16384;
  237. end;
  238.  
  239. (*------------------------------------------------*)
  240.  
  241. procedure DrawFloor(x,y, angle : integer; Coords : pointer); assembler;
  242. var
  243.     mappos,tablepos : word;
  244.     xadd,yadd,
  245.     mapxadd,mapyadd : integer;
  246.     height, counts : word;
  247. asm
  248.     push    ds
  249.     mov    es,SEGA000
  250.     mov    di,100*320
  251.     mov    ax,WORD PTR [map+2]
  252.     {mov fs,ax} DB $8E,$E0
  253.     mov    ax,WORD PTR [Coords+2]
  254.     {mov gs,ax} DB $8E,$E8
  255.     mov    ax,WORD PTR [Coords]
  256.     mov    [tablepos],ax
  257.     mov    ds,WORD PTR [tiles+2]
  258.  
  259.     cld
  260.     mov    [height],LINES
  261. @y_run:
  262.  
  263.     mov    si,[tablepos]
  264.  
  265.     DB GS; mov    ax,[si+4]
  266.     cmp    [angle],256
  267.     jb        @anglelow1
  268.     neg    ax
  269. @anglelow1:
  270.     mov    [xadd],ax
  271.     mov    [mapxadd],1
  272.     or        ax,ax
  273.     jns    @mapxup
  274.     mov    [mapxadd],-1
  275. @mapxup:
  276.  
  277.     DB GS; mov    ax,[si+6]
  278.     cmp    [angle],256
  279.     jb        @anglelow2
  280.     neg    ax
  281. @anglelow2:
  282.     mov    [yadd],ax
  283.     mov    [mapyadd],256
  284.     or        ax,ax
  285.     jns    @mapyup
  286.     mov    [mapyadd],-256
  287. @mapyup:
  288.  
  289.     DB GS; mov    dx,[si]
  290.     DB GS; mov    cx,[si+2]
  291.     cmp    [angle],256
  292.     jb        @anglelow3
  293.     neg    cx
  294.     neg    dx
  295. @anglelow3:
  296.     add    dx,[x]
  297.     add    cx,[y]
  298.  
  299.     mov    bx,dx                    {Find first tile}
  300.     mov    ax,cx
  301.     shr    ax,5
  302.     shr    bx,5
  303.     mov    bh,al
  304.     mov    [mappos],bx
  305.     DB FS; mov al,[bx]        {get tile-index from map}
  306.     mov    ah,al                    {find map position in map-buffer}
  307.     and    al,7
  308.     shr    ah,3
  309.     shl    ax,5
  310.     mov    si,ax
  311.  
  312.     shl    dx,11
  313.     shl    cx,11
  314.     xor    dx,$8000
  315.     xor    cx,$8000
  316.  
  317.     mov    [counts],160
  318. @x_run:
  319.     mov    bh,dh        {get x-position of pixel}
  320.     mov    bl,ch        {get y-position of pixel}
  321.     shr    bx,3
  322.     and    bx,$1F1F
  323.     mov    al,[si+bx]    {get that pixel}
  324.     mov    ah,al
  325.     stosw                    {store it... well, we draw it twice to gain speed!}
  326.  
  327.     add    dx,[xadd]            {add to x-slope}
  328.     jno    @noxadd
  329.     mov    bx,[mappos]
  330.     add    bx,[mapxadd]
  331.     mov    [mappos],bx
  332.     DB FS; mov al,[bx]        {get new tile-index from map}
  333.     mov    ah,al                    {find tile position in tile-buffer}
  334.     and    al,7
  335.     shr    ah,3
  336.     shl    ax,5
  337.     mov    si,ax
  338. @noxadd:
  339.  
  340.     add    cx,[yadd]            {add to y-slope}
  341.     jno    @noyadd
  342.     mov    bx,[mappos]
  343.     add    bx,[mapyadd]
  344.     mov    [mappos],bx
  345.     DB FS; mov al,[bx]        {get new tile-index from map}
  346.     mov    ah,al                    {find tile position in tile-buffer}
  347.     and    al,7
  348.     shr    ah,3
  349.     shl    ax,5
  350.     mov    si,ax
  351. @noyadd:
  352.  
  353.     dec    [counts]
  354.     jnz    @x_run
  355.  
  356.     add    [tablepos],8
  357.     dec    [height]
  358.     jnz    @y_run
  359.  
  360.     pop    ds
  361. end;
  362.  
  363.  
  364. (*------------------------------------------------*)
  365.  
  366. procedure RunOnce;
  367. var
  368.     i : integer;
  369. begin
  370.     VBLANK;
  371. {$IFDEF DEBUG}    SetRGB(0,20,0,0); {$ENDIF}
  372.     MoveHero;
  373.     DrawFloor(xpos,ypos, angle, CoordPtr[angle AND 255]);
  374. {$IFDEF DEBUG}    SetRGB(0,0,0,0); {$ENDIF}
  375. end;
  376.  
  377.  
  378. begin
  379.     if NOT MouseDriverPresent then begin writeln('No mouse...'); halt; end;
  380.  
  381.     SetScreenMode($13);
  382.     InitDemo;
  383.     repeat RunOnce until KeyPressed;
  384.     UninitDemo;
  385.     SetScreenMode(TEXTMODE);
  386. end.
  387.